// soule // HEURISTIQUE
// Il va nous servir pour choisir quel emplacement joue a noeud n(i)
// On va se base sur un vecteur qui garde tous les mouvements possible, classé avec leur meilleur ratio
// de victoires / nombres de fois joues

#include "vecteurRave.h"
#include "../EPlateau.h"

#include <gmpxx.h>

//mpz_class vecteurRave::limite = * new mpz_class(pow(10,50));


ofstream fichier2("addMtrick.txt", ios::ate | ios::out);
// CONSTRUCTEURS
// cree un vecteur rave contenant toutes les pieces orientées
vecteurRave::vecteurRave() {
    cout<<"ERREUR DE CONSTRUCTEUR: si pas d'appel d'initialisateur apres"<<endl;
}

vecteurRave::vecteurRave(vector<Po> listePo, Coord p) {
    initialisateur(listePo, p);
}

void vecteurRave::initialisateur(vector<Po> listePo, Coord p) {
    cout<<"INITIALISATION ! ! !"<<endl;
    taille = listePo.size();
    cout<<listePo.size()<<endl;
    position = p;
    maillonUCT m;
    maillonUCT * prec = NULL;

    int nbBord=0;
    if(p.x == 0 || p.x == taille - 1 ){
        nbBord++;
    }
    if(p.y == 0){
        nbBord++;
    }
    //tableMaillons.resize(listePo.size());

    tableMaillons = (maillonUCT*)malloc(sizeof(maillonUCT)*taille);

    for (int i =0; i<listePo.size(); i++) {
        m.piece = listePo[i];
        //cout<<poToPiece(m.piece)<<endl;
      //  m.score = listePo.size()/4 ;
      //  m.nbJeux = 1;

		int taille = sqrt(listePo.size()/4);

       //m.proba =  new mpq_class(1,((taille-1)*(taille-1))); //initialisation de la proba d'être la bonne pièce
		m.proba = (double)1/((taille-1)*(taille-1));


        m.suivant = prec;
        m.libre=true;
        tableMaillons[i]=m;
        /*	 if (i==0) {premier=&tableMaillons.back();
             cout<<"<0:> "<<poToPiece(premier->piece)<<" | "<<poToPiece(tableMaillons[0].piece)<<endl;
        	 } */
        if (prec) {
            prec->precedent = &tableMaillons[i];
        }

        prec = &tableMaillons[i];
        //cout<<"<b:"<<i<<"> "<<premier<<" : "<<poToPiece(premier->piece)<<" | "<<poToPiece(tableMaillons[0].piece)<<endl;
    }
    tableMaillons[listePo.size()-1].precedent = NULL;
    //cout<<"<1:> "<<poToPiece(premier->piece)<<" | "<<poToPiece(tableMaillons[0].piece)<<endl;

    racine = prec;
//   cout<<"racine : "<<poToPiece(racine->piece)<<" | "<<poToPiece(tableMaillons[0].piece)<<endl;
    //cout<<"<1.5:> "<<poToPiece(premier->piece)<<endl;

    courant = racine;

    cout<<"racine: "<<racine<<" / "<<racine->suivant<<" / "<<racine->suivant->suivant <<endl;
    for (int t = 0; t<taille; t++) {
        cout<<&(tableMaillons[t])<<endl;
    }

    //exit(0);
}

//constructeur par copie
vecteurRave::vecteurRave(vecteurRave * l) {

    taille = l->taille;
    cout<<"taille: "<<taille<<endl;

    tableMaillons = (maillonUCT*)malloc(sizeof(maillonUCT)*taille);
    cout<<"test"<<endl;
    maillonUCT mTest;// = l->tableMaillons[0];


    cout<<"..."<<endl;
    mTest.libre=l->tableMaillons[0].libre;
    mTest.lu=l->tableMaillons[0].lu;
    mTest.nbJeux=l->tableMaillons[0].nbJeux;
    mTest.nbJeuxTemp=l->tableMaillons[0].nbJeuxTemp;
    mTest.piece=l->tableMaillons[0].piece;
    mTest.score=l->tableMaillons[0].score;
    mTest.scoreTemp=l->tableMaillons[0].scoreTemp;
	mTest.precedent = NULL;
	mTest.suivant = NULL;
	cout<<"!"<<endl;

    cout<<"avant le drame"<<endl;

   // tableMaillons[0].proba = new mpq_class(1,((taille-1)*(taille-1)));

	 tableMaillons[0].proba = (double)1/((taille-1)*(taille-1));

    cout<<"apres le drame"<<endl;
		tableMaillons[0] = mTest;

    //     tableMaillons.resize(l->taille);
    cout<<"construction PAR COPIE d'un vecteur rave..."<<endl;
    position = l->position;
    if (l->racine== NULL) {
        racine = NULL;
    } else {

        // maillonUCT * monMaillon = (struct maillonUCT *) malloc(sizeof(maillonUCT));
        //  (*monMaillon) = (* l->racine);
        cout<<"mm : racine de l'autre: "<<poToPiece(l->racine->piece)<<endl;
        // tableMaillons.resize(l->tableMaillons.size());

        for (int t = 0; t<taille; t++) {
            cout<<&(l->tableMaillons[t])<<endl;
        }
        cout<<"--------------------------"<<endl;
        cout<<l->racine<<" / "<<l->racine->suivant<<" / "<<l->racine->suivant->suivant <<" - "<<  &(l->tableMaillons[0])  <<" - "<<  &tableMaillons[0]<<endl;
        cout<<&(l->tableMaillons[0])  <<" - "<<&(l->tableMaillons[1])  <<" - "<<&(l->tableMaillons[2])  <<" - "<<&(l->tableMaillons[3])  <<" - "<<&(l->tableMaillons[4])  <<" - "<<endl;
//                cout<<(int)&(l->tableMaillons[1]) - (int)&(l->tableMaillons[0]) <<" ... "<<(int)&(l->tableMaillons[3]) - (int)&(l->tableMaillons[0])<<endl;
        cout<<"entre deux fors"<<endl;

        cout<<racine<<endl;
        courant = racine;
        int k= 0;


        for (int i = 0; i< l->taille;i++) {
            cout<<"deuxieme for, i = "<<i<<endl;
            //mise dans le tableau
            cout<<l->tableMaillons[i].score<<endl;
            //cout<<l->tableMaillons[i].proba<<endl;
            cout<<":-)"<<endl;
            tableMaillons[i] = l->tableMaillons[i];
            cout<<"plante?"<<endl;
            cout<<tableMaillons[i].piece.p<<endl;

            //double chainage
            if  (l->tableMaillons[i].suivant) {
                tableMaillons[i].suivant = l->tableMaillons[i].suivant -  &(l->tableMaillons[0]) + &tableMaillons[0] ; //truc HORRIBLE
            }

            if  (l->tableMaillons[i].precedent) {
                tableMaillons[i].precedent = l->tableMaillons[i].precedent -  &(l->tableMaillons[0]) + &tableMaillons[0] ; //truc HORRIBLE²
            }
        }

        racine = l->racine -  &(l->tableMaillons[0]) + &tableMaillons[0];
        cout<<"racine copiée: "<<racine<<endl;
        cout<<"tableau copié:"<<endl;
        for (int t = 0; t<taille; t++) {
            cout<<&(tableMaillons[t])<<" :"<<tableMaillons[t].piece.p<<endl;
        }


        cout<<"test constructeur copie vecteur rave: "<<endl;
        int cpt=0;
        for (maillonUCT* maillonCourant = racine->suivant; maillonCourant != NULL; maillonCourant = maillonCourant->suivant) {
            cout<<"coucou! "<<endl;
            cout<<cpt<<": "<<maillonCourant->piece.p<<" ,score: "<<maillonCourant->proba<<endl;
            cpt++;


            /*	(*monMaillon) = (* maillonCourant); //truc horrible

            monMaillon->suivant = (maillonUCT *) malloc(sizeof(maillonUCT));

            // monMaillon->suivant->precedent= monMaillon;

            monMaillon = monMaillon->suivant;

            tableMaillons[poToInt(monMaillon->piece)]=(*monMaillon);
            */
        }
    }
}



// ACCESSEURS
maillonUCT * vecteurRave::getRacine() {
    return this->racine ;
}

int vecteurRave::getNbMaillon() {
    return taille;
}

/*
maillonUCT *vecteurRave::existe(maillonUCT *m) {
    maillonUCT *maillonCourant=racine;
    while (maillonCourant != NULL) {
        if (maillonCourant->coup.x == m->coup.x && maillonCourant->coup.y == m->coup.y && maillonCourant->coup.c == m->coup.c) {
            return maillonCourant;
        }
        maillonCourant=maillonCourant->suivant;
    }
    return NULL;
}
*/
// METHODES
// ajoute un maillon dans la liste pour la garder dans l'ordre decroissant le ratio des Coup
/*
void vecteurRave::ajouterMaillon(maillonUCT* m) {
    //cerr<<endl<< "    debut ajout maillon" <<endl ;

    //afficherListeMaillons() ;

    //cerr <<"  On va ajouter le maillon :"<< m->coup.x << "," << m->coup.y << "," << m->coup.c << ";" << m->score << "," << m->nbJeux << endl;
    maillonUCT* maillonCourant, *maillonPrecedent ;
    maillonCourant = racine ;
    maillonPrecedent = racine ;
    double ratioCourant, ratioAjout ;
    int compteurMaillon = 0 ;


    // on parcoure la liste pour trouver le premier ratio inferieur au ratio du maillon
    // qu'on veut ajouter
    cerr<<"    avant le if"<<endl ;
    if (maillonCourant == NULL) {
        // si pas de maillons on l'initialise
        cerr<<"    si pas de maillon"<<endl ;
        racine = m ;
        racine->suivant = NULL ;
    } else { // si ya deja des maillons
        cerr<<"    si ya deja des maillons"<<endl ;
        ratioCourant = (double)maillonCourant->score / (double)maillonCourant->nbJeux ;
        ratioAjout = (double)m->score / (double)m->nbJeux ;
        cerr<<"3"<<endl ;
        cerr<<"    on va comparer ratiocourant : "<<ratioCourant<<" avec ratioAjout : "<<ratioAjout<<endl ;
        while (ratioCourant > ratioAjout && maillonCourant != NULL) {
            cerr<<"1"<<endl ;
            maillonPrecedent = maillonCourant ;
            maillonCourant = maillonCourant->suivant ;
            compteurMaillon++ ;
            cerr<<"2"<<endl ;
            if (maillonCourant != NULL) {
                ratioCourant = (double)maillonCourant->score / (double)maillonCourant->nbJeux ;
                ratioAjout = (double)m->score / (double)m->nbJeux ;
                cerr<<"3"<<endl ;
                cerr<<"    on va comparer ratiocourant : "<<ratioCourant<<" avec ratioAjout : "<<ratioAjout<<endl ;
                cerr<<"4"<<endl ;
            }

        }
        if (maillonCourant == NULL) { // si fin de la liste
            //on ajoute a la toute fin
            cerr<<"    si fin de la liste"<<endl ;
            maillonPrecedent->suivant = m ;
            m->suivant=NULL ;
        } else { // il faut brancher precedent avec m et m avec courant
            // on gere le cas ou y'a que 2 maillons
            cerr<<"    on a compteurMaillon = "<<compteurMaillon<<endl ;
            if (compteurMaillon == 0) {
                cerr<<"    on va brancher le ratio dajout "<<ratioAjout<<" en tant que racine, et il pointera sur celui qui etait avant : "<<ratioCourant<<endl ;
                this->racine = m ;
            } else {
                cerr<<"    on va brancher le ratioPrecedent "<<(double)maillonPrecedent->score / (double)maillonPrecedent->nbJeux<<" au ratioAjout "<<ratioAjout<<" et au ratioCourant "<<ratioCourant<<endl ;

                maillonPrecedent->suivant = m ;
            }
            m->suivant = maillonCourant ;
        }
    }
    cerr<<"        AVANT DE quitter"<<endl ;
    afficherListeMaillons() ;
    this->nbMaillon++ ;
}

*/

double vecteurRave::getRatio(maillonUCT * monMaillon) {
    /*cout<<"  - - - - - - "<<endl;
    cout<<"getRatio: "<<endl;
    cout<<monMaillon->score<<" - "<<monMaillon->nbJeux<<" - "<<(double)monMaillon->score<<" - "<< (double)monMaillon->nbJeux<<" - "<<((double)monMaillon->score / (double)monMaillon->nbJeux) <<endl;
    cout<<"  - - - - - - "<<endl;
    //int pause;
    //cin>>pause;
    */
    //cout<<"getRatio : "<<monMaillon->score<<" / "<<monMaillon->nbJeux <<" : "<<(((double)monMaillon->score) + 0.5)<<" / "<< (((double)monMaillon->nbJeux)+1) <<" : "<<(((double)monMaillon->score) + 0.5) / (((double)monMaillon->nbJeux)+1)<<endl;

  return  monMaillon->proba;
  //  return ( ((double)monMaillon->score)  / ((double)monMaillon->nbJeux)) - log((double)monMaillon->nbJeux)/10;

    //return ( ((double)monMaillon->score)  / ((double)monMaillon->nbJeux * monMaillon->nbJeux)) ;
}

/*
// trouver le coup disponible avec le meilleur ratio. Renvoi -10 -10 si aucun ratio sup à 0.5
Coup vecteurRave::trouverMeilleurMaillon()
{

    maillonUCT* maillonCourant  = racine ;
    //cout<<"pre while"<<endl;
    while (maillonCourant != NULL && (maillonCourant->lu == false  && maillonCourant->libre == false))
    {

        //cout<<maillonCourant<<endl;
        //cout<<" - "<<maillonCourant->suivant <<endl;
        maillonCourant = maillonCourant->suivant ;
        //cout<<"n w"<<endl;
    }
    if (maillonCourant != NULL && maillonCourant->getRatio() > 0.5)
    {
        maillonCourant->libre = true;
        return maillonCourant->coup ;
    }
    else   // soit la liste est vide, soit tous les coups ont deja ete joues
    {
        Coup temp ;
        temp.x = -10 ;
        temp.y = -10 ;
        temp.c = VIDE;
        return temp ;
    }
}
*/

// trouver le coup disponible avec le meilleur ratio. TIENS COMPTE DES COUPS POSSIBLES SUR LE GOBAN ACTUEL.
Po vecteurRave::trouverMeilleurMaillon( EPlateau * p) {

    maillonUCT* maillonCourant  = racine ;
    int i =0;
    while (maillonCourant != NULL &&  !p->coupJouable( maillonCourant->piece, position)) {
        i++;
        //cout<<"lu : "<<poToPiece(maillonCourant->piece)<<endl;
        maillonCourant = maillonCourant->suivant ;

    }

    if (maillonCourant != NULL && p->coupJouable( maillonCourant->piece, position) ) {
        return maillonCourant->piece;
    } else { // soit la liste est vide, soit tous les coups ont deja ete joues
        cout<<i<< "coups lus"<<endl;
        cout<<"pas de coups jouables..."<<endl;
        Po vide ;
        vide.p.numero = 0 ;
        return vide;
    }
}

// renvoi le ratio correspondant au Coup donne. Renvoi -1 si le coup n'existe pas
/*
double vecteurRave::trouverRatio(Coup c)
{
    maillonUCT* maillonCourant = this->racine ;
    while (maillonCourant != NULL && maillonCourant->coup.x != c.x && maillonCourant->coup.y != c.y)
    {
        maillonCourant = maillonCourant->suivant ;
    }
    if (maillonCourant == NULL)   // si on est a la fin sans avoir trouver le coup
    {
        return 0 ;
    }
    else   // si on a trouvé le bon coup
    {
        double ratio = maillonCourant->getRatio();
        return ratio ;
    }
}
*/

//mise a jour du vecteur rave
void vecteurRave::majValeurs(int score, int emplacement, double monEmbranchement, double emBranchementTotal) {
    //cout<<"majValeurs: "<<endl;
    //cout<<score<<" - "<<emplacement<<endl;
    tableMaillons[emplacement].score += score;
    tableMaillons[emplacement].nbJeux ++;

    //cout<<"on va scorer"<<endl;

    tableMaillons[emplacement].scoreTemp += score;
    tableMaillons[emplacement].nbJeuxTemp ++;
    //cout<<"on va planter: "<<monEmbranchement<<" embanchemenTotal: "<<emBranchementTotal<<endl;
	 tableMaillons[emplacement].proba *= (1 - 1 * (emBranchementTotal/monEmbranchement)) * (1-emBranchementTotal) ;

//simplification magique
/*
    while( (tableMaillons[emplacement].proba->get_num()) >limite && (tableMaillons[emplacement].proba->get_den()) > limite){
           // cout<<"simplification : "<<proba<<" : "<<proba.get_num()<<" / "<<proba.get_den()<<endl;
            //int pause;
            //cin>> pause;
            tableMaillons[emplacement].proba->get_num() /= pow(10,5);
            tableMaillons[emplacement].proba->get_den() /= pow(10,5);

        }
*/

//retriage de la liste chainée
    //cout<<"avancement ... "<<endl;

    while ((tableMaillons[emplacement].suivant!=NULL) &&  (tableMaillons[emplacement].suivant->score > tableMaillons[emplacement].score)) {
    //    cout<<"on va inverser avec un suivant"<<endl;
        if (!tableMaillons[emplacement].precedent) {
            racine = tableMaillons[emplacement].suivant;
            tableMaillons[emplacement].precedent = tableMaillons[emplacement].suivant;
            tableMaillons[emplacement].suivant = tableMaillons[emplacement].suivant->suivant;
            tableMaillons[emplacement].suivant->precedent = &tableMaillons[emplacement];
            tableMaillons[emplacement].precedent->suivant = &tableMaillons[emplacement];
            tableMaillons[emplacement].precedent->precedent = NULL;
        } else if (!tableMaillons[emplacement].suivant->suivant) {
            tableMaillons[emplacement].suivant->precedent = tableMaillons[emplacement].precedent;
            tableMaillons[emplacement].precedent->suivant = tableMaillons[emplacement].suivant;
            tableMaillons[emplacement].suivant->suivant = &tableMaillons[emplacement];
            tableMaillons[emplacement].precedent = tableMaillons[emplacement].suivant;
            tableMaillons[emplacement].suivant = NULL;
        } else { //cas "normal"
            tableMaillons[emplacement].suivant->precedent = tableMaillons[emplacement].precedent;
            tableMaillons[emplacement].suivant = tableMaillons[emplacement].suivant->suivant;
            tableMaillons[emplacement].precedent->suivant = tableMaillons[emplacement].suivant->precedent;
            tableMaillons[emplacement].suivant->precedent = &tableMaillons[emplacement];
            tableMaillons[emplacement].precedent->suivant->suivant = &tableMaillons[emplacement];
            tableMaillons[emplacement].precedent = tableMaillons[emplacement].precedent->suivant;
        }
    }
  //  cout<<"2"<<endl;
    while ((tableMaillons[emplacement].precedent!=NULL) &&  (tableMaillons[emplacement].precedent->score < tableMaillons[emplacement].score)) {

    //    cout<<"on va inverser avec un précédent"<<endl;

        if (!tableMaillons[emplacement].suivant) {
      //      cout<<"et 1"<<endl;
            tableMaillons[emplacement].suivant = tableMaillons[emplacement].precedent;
            tableMaillons[emplacement].precedent = tableMaillons[emplacement].precedent->precedent;
            tableMaillons[emplacement].precedent->suivant = &tableMaillons[emplacement];
            tableMaillons[emplacement].suivant->precedent = &tableMaillons[emplacement];
            tableMaillons[emplacement].suivant->suivant = NULL;

        } else if (!tableMaillons[emplacement].precedent->precedent) {
            //cout<<"et 2"<<endl;
            racine = & tableMaillons[emplacement];
            tableMaillons[emplacement].precedent->suivant = tableMaillons[emplacement].suivant;
            tableMaillons[emplacement].suivant->precedent = tableMaillons[emplacement].precedent;
            tableMaillons[emplacement].precedent->precedent = &tableMaillons[emplacement];
            tableMaillons[emplacement].suivant = tableMaillons[emplacement].precedent;
            tableMaillons[emplacement].precedent = NULL;

        } else { //cas "normal"
        //    cout<<"et troisssssssssssssssssss"<<endl;
            //cout<<"précédent->précédent: "<<tableMaillons[emplacement].precedent->precedent<<endl;
            //cout<<"précédent->précédent->suivant: "<<tableMaillons[emplacement].precedent->precedent->suivant<<endl;
            tableMaillons[emplacement].precedent->suivant = tableMaillons[emplacement].suivant;
            tableMaillons[emplacement].precedent = tableMaillons[emplacement].precedent->precedent;
            //cout<<"precedent: "<<tableMaillons[emplacement].precedent<<endl;
            //cout<<"suivant: "<<tableMaillons[emplacement].precedent->suivant<<endl;
            tableMaillons[emplacement].suivant->precedent = tableMaillons[emplacement].precedent->suivant;
            tableMaillons[emplacement].precedent->suivant = &tableMaillons[emplacement];
            tableMaillons[emplacement].suivant->precedent->precedent = &tableMaillons[emplacement];
            tableMaillons[emplacement].suivant = tableMaillons[emplacement].suivant->precedent;

        }


    }
}




void vecteurRave::majVraiMaillon(maillonUCT * maillonCherche,vecteurRave * listeChainee) {
    maillonUCT * maillonListe=listeChainee->racine; //le maillon de la VRAIE liste
//maillonUCT * maillonCourant = ;
    maillonUCT m1;
    maillonUCT m2;
    m1.nbJeux =1;
    m1.score = 1000000;
    m1.suivant= &m2;

    m2.nbJeux =1;
    m2.score =1000000;
    m2.suivant= maillonListe;

    maillonUCT* maillonPrePrecedent = &m1;

//parcours de la VRAIE liste par le préprécédent
    while (maillonPrePrecedent->suivant->suivant!=NULL  && (!(maillonPrePrecedent->suivant->suivant->piece== maillonCherche->piece ) )) {
        maillonPrePrecedent=maillonPrePrecedent->suivant;
    }
    if  (maillonPrePrecedent->suivant->suivant!=NULL) {
        //on a trouvé le bon maillon
        maillonListe=maillonPrePrecedent->suivant->suivant;


        maillonListe->nbJeux+= maillonCherche->nbJeuxTemp ;
        maillonCherche->nbJeuxTemp =0;

        //maillonCourant->libre = true ;
        if (maillonCherche->scoreTemp>0) {
            //cout <<"Coup : "<<(int)maillonCourant->coup.x<<" - "<<(int)maillonCourant->coup.y<<" : "<<maillonCourant->coup.c<<" : "<<maillonCourant->nbJeux<<" / "<<maillonCourant->score<<endl;
            //   cout<<"coup de winneur"<<endl;
            maillonListe->score+= maillonCherche->scoreTemp;
            maillonCherche->scoreTemp =0;
            // cout<<maillonPrePrecedent<<" - "<<maillonPrePrecedent->suivant<<" - "<<maillonPrePrecedent->suivant->suivant<<" = "<<maillonCourant<<" - "<<maillonCourant->suivant<<endl;
            if (getRatio(maillonListe) > getRatio(maillonPrePrecedent->suivant)) {
                //  cout<<"switch : "<<(double)maillonCourant->score / maillonCourant->nbJeux<<" vs "<<(double) maillonPrePrecedent->suivant->score / maillonPrePrecedent->suivant->nbJeux<<endl;
                if (listeChainee->racine == maillonPrePrecedent->suivant) {
                    listeChainee->racine = maillonListe;
                }
                //SWITCH de cellules sur la VRAIE liste
                maillonPrePrecedent->suivant->suivant = maillonListe->suivant;
                maillonListe->suivant = maillonPrePrecedent->suivant;
                maillonPrePrecedent->suivant = maillonListe;
                maillonListe = maillonListe->suivant;
            }
            //cout<<maillonPrePrecedent<<" - "<<maillonPrePrecedent->suivant<<" - "<<maillonPrePrecedent->suivant->suivant<<" = "<<maillonCourant<<" - "<<maillonCourant->suivant<<" = "<<maillonPrePrecedent->suivant->suivant<<endl;
        }

    } else {
        cout<<"erreur dans majVraiMaillon, on a pas trouvé le maillon du coup donné."<<endl;// : <<(int)maillonCherche->.x <<" - "<<(int)maillonCherche->coup.y<<endl;
    }
}


// augmente de 1 le nombre de jeux et remet les coups a 'libre'
// augmente aussi les victoires si le boolean est a vrai
void vecteurRave::partieFinie(vecteurRave * listeChainee) {
    maillonUCT* maillonCourant = this->racine; // le maillon courant de la liste CUSTOM
// Parcours de la liste CUSTOM
    while (maillonCourant != NULL) {
        //si le maillon courant de la liste custom a été utilisé
        if (maillonCourant->nbJeuxTemp > 0) {
            //on cherche le maillon original qui correspond:
            majVraiMaillon(maillonCourant, listeChainee);
        }
        maillonCourant = maillonCourant->suivant ;
    }
}

bool test(int n) {
    //cout<<"test : "<<n<<endl;
    return 1;
}
// On veut jouer ce coup. La fonction verifie que le coup n'existe pas
// deja Si  non, il est rajouter a la liste chainee



// augmente de 1 le nombre de jeux et remet les coups a 'libre'
// augmente aussi les victoires si le boolean est a vrai
void vecteurRave::partieFinie(bool b) {

    maillonUCT* maillonCourant = this->racine ;
    maillonUCT* maillonTemp;
    maillonUCT m1;
    maillonUCT m2;
    m1.nbJeux =1;
    m1.score = 1000000;
    m1.suivant= &m2;

    m2.nbJeux =1;
    m2.score =1000000;
    m2.suivant= maillonCourant;

    maillonUCT* maillonPrePrecedent = &m1;

    while (maillonCourant != NULL) {
        maillonCourant->lu = false;
        /*cout<<"while de partie fini"<<endl;
        cout<<maillonCourant->coup.x<<" - "<<maillonCourant->coup.y<<endl;
        cout<<maillonPrePrecedent->coup.x<<" - "<<maillonPrePrecedent->coup.y<<endl; */
        if (maillonCourant->libre == false) {
            maillonCourant->nbJeuxTemp++ ;
            maillonCourant->nbJeux++ ;

            maillonCourant->libre = true ;
            if (b == true) {
                //cout <<"Coup : "<<(int)maillonCourant->coup.x<<" - "<<(int)maillonCourant->coup.y<<" : "<<maillonCourant->coup.c<<" : "<<maillonCourant->nbJeux<<" / "<<maillonCourant->score<<endl;
                //   cout<<"coup de winneur"<<endl;
                maillonCourant->scoreTemp++ ;
                maillonCourant->score++ ;
                // cout<<maillonPrePrecedent<<" - "<<maillonPrePrecedent->suivant<<" - "<<maillonPrePrecedent->suivant->suivant<<" = "<<maillonCourant<<" - "<<maillonCourant->suivant<<endl;
                /*  if((double)maillonCourant->score / maillonCourant->nbJeux > ( (double) maillonPrePrecedent->suivant->score / maillonPrePrecedent->suivant->nbJeux) ){
                    //  cout<<"switch : "<<(double)maillonCourant->score / maillonCourant->nbJeux<<" vs "<<(double) maillonPrePrecedent->suivant->score / maillonPrePrecedent->suivant->nbJeux<<endl;
                      if (racine == maillonPrePrecedent->suivant){
                          racine = maillonCourant;
                      }
                      maillonPrePrecedent->suivant->suivant = maillonCourant->suivant;
                      maillonCourant->suivant = maillonPrePrecedent->suivant;
                      maillonPrePrecedent->suivant = maillonCourant;
                      maillonCourant = maillonCourant->suivant;
                  }
                  //cout<<maillonPrePrecedent<<" - "<<maillonPrePrecedent->suivant<<" - "<<maillonPrePrecedent->suivant->suivant<<" = "<<maillonCourant<<" - "<<maillonCourant->suivant<<" = "<<maillonPrePrecedent->suivant->suivant<<endl;
                */
            }
        }
        //cout<<"preparation du prochain passage"<<endl;
        maillonCourant = maillonCourant->suivant ;
        maillonPrePrecedent = maillonPrePrecedent->suivant;
    }
    last = maillonPrePrecedent->suivant;
    //cout<<"last 1 : "<<last<<" - last 1 s : "<<last->suivant<<endl;
    //cout<<"last1 coup : "<<(int)last->coup.x<<" - "<<(int)last->coup.y<<" - "<<last->coup.c<<endl;
}


/*
void vecteurRave::veutJouer(Coup c)
{
    //cout<<"veutjouercoup : "<<(int)c.x<<" - "<<(int)c.y<<" : "<<c.c<<endl;
    //cout<<"vj"<<endl;
    maillonUCT* maillonCourant ;
    maillonCourant = racine ;
    //maillonUCT *maillonAvant = maillonCourant;
    //cout<<"pre boucle"<<endl;
    if (racine == NULL)
    {
        maillonUCT * m = (struct maillonUCT *) malloc(sizeof(maillonUCT));
        m->coup = c ;
        m->score = 0 ;
        m->nbJeux = 0 ;
        m->scoreTemp = 0;
        m->nbJeuxTemp = 0;
        m->libre = false ;
        m->lu = false;
        m->suivant = NULL;
        racine = m;
    }
    else
    {
        while (maillonCourant->suivant != NULL && !(maillonCourant->coup.x == c.x && maillonCourant->coup.y == c.y))
        {
            //cout<<"while : "<<maillonCourant<<" - "<<maillonCourant->suivant <<endl;
            maillonCourant = maillonCourant->suivant ;
            // cout<<"while 2 : "<<maillonCourant<<endl;
        }
        // on a parcouru toute la liste, le coup n'existait pas, on l'ajoute

        if ( !(maillonCourant->coup.x == c.x && maillonCourant->coup.y == c.y))
        {
            //cout<<"if"<<endl;
            maillonUCT * m = (struct maillonUCT *) malloc(sizeof(maillonUCT));
            m->coup = c ;
            //cout<<" c v j : "<<(int)c.x<<" - "<<(int)c.y<<" : "<<c.c<<endl;
            m->score = 0 ;
            m->nbJeux = 0 ;
            m->scoreTemp = 0 ;
            m->nbJeuxTemp = 0 ;
            m->libre = false ;
            m->lu = false;
            m->suivant = NULL;
            maillonCourant->suivant = m;
            //cout<<"fin if"<<endl;
        }
        else   // on a trouvé le coup en question
        {
            maillonCourant->libre =  false ;
        }
        //cout<<"fin vj"<<endl;
    }

}

*/



void vecteurRave::addMaillonTrick(Po pieceO, int x ) {
    // fichier2<<(int)c.place.x<<" - "<<(int)c.place.y<<" : "<<x<<endl;
    maillonUCT* maillonTemp;
    maillonUCT m1;
    maillonUCT m2;
    m1.nbJeux =1;
    m1.score = 1000000;
    m1.suivant= &m2;

    m2.nbJeux =1;
    m2.score =1000000;
    m2.suivant= racine;


    maillonUCT* maillonCourant = &m1;

    while (maillonCourant->suivant->suivant != NULL && !(maillonCourant->suivant->suivant->piece == pieceO)) {
        maillonCourant = maillonCourant->suivant;
    }

    if (maillonCourant->suivant->suivant != NULL) { // Le maillon existe deja.
        //fichier2<<" avant :  "<<(int)maillonCourant->suivant->suivant->coup.x<<" - "<<(int)maillonCourant->suivant->suivant->coup.y<<" : "<<maillonCourant->suivant->suivant->score<<" / "<<maillonCourant->suivant->suivant->nbJeux<<endl;
        maillonCourant->suivant->suivant->nbJeux += abs(x/10); //remetre +=
        if (x>1) {
            maillonCourant->suivant->suivant->score += (abs(x/10) -2*sqrt(x/10 + 1) ); //remetre +=
        }

        //fichier2<<" apres :  "<<(int)maillonCourant->suivant->suivant->coup.x<<" - "<<(int)maillonCourant->suivant->suivant->coup.y<<" : "<<maillonCourant->suivant->suivant->score<<" / "<<maillonCourant->suivant->suivant->nbJeux<<endl;
        while ( getRatio(maillonCourant->suivant) < getRatio(maillonCourant->suivant->suivant)) { //A REMPLACER PAR UN TRI FUSION A LA FIN DES AJOUTS
            if (racine == maillonCourant->suivant) {
                racine = maillonCourant->suivant->suivant;
            }
            maillonTemp = maillonCourant->suivant->suivant;
            maillonCourant->suivant->suivant = maillonCourant->suivant->suivant->suivant;
            maillonTemp->suivant = maillonCourant->suivant;
            maillonCourant->suivant = maillonTemp;

            //on recule d'un pas ds la liste.
            maillonTemp = &m1;
            while (maillonTemp->suivant != maillonCourant) {
                maillonTemp = maillonTemp->suivant;
            }
            maillonCourant = maillonTemp;
        }

    } else { //Si le maillon n'existe aps dans la liste...

        maillonCourant = &m2;


        while (maillonCourant->suivant !=NULL && (maillonCourant->suivant->score   > x)) {
            maillonCourant = maillonCourant->suivant;
        }

        maillonUCT * m = (struct maillonUCT *) malloc(sizeof(maillonUCT));
        m->piece = pieceO ;
        //cout<<" c v j : "<<(int)c.x<<" - "<<(int)c.y<<" : "<<c.c<<endl;
        m->nbJeux = abs(x)/4;
        if (x>0) {
            m->score = (abs(x) -sqrt(x) +0.5*abs(x))/4;
        } else {
            m->score = 1;
        }

        m->libre = true ;
        m->lu = false;
        m->suivant = maillonCourant->suivant;
        m->nbJeuxTemp=0;
        m->scoreTemp=0;
        maillonCourant->suivant = m;



        if (maillonCourant == &m2) {
            racine = m;
        }
    }
}

void vecteurRave::raz() {
    if (racine != NULL) {
        delMaillon(racine);
        racine = NULL;
    }
}

void vecteurRave::delMaillon( maillonUCT * m ) {
    if (m->suivant != NULL)
        delMaillon(m->suivant);
    delete m;
}



void vecteurRave::divise(int n) {
    for (maillonUCT* maillonCourant = racine; maillonCourant != NULL; maillonCourant = maillonCourant->suivant) {
        maillonCourant->nbJeux = (maillonCourant->nbJeux / (n+1)) + 2*n;
        maillonCourant->score = (maillonCourant->score / (n+1) )+ 1*n;  // /!\ a changer !?
    }
}


void vecteurRave::afficherListeMaillons() {
    cout<<" -> Affichage de la liste des maillons : "<<endl ;
    maillonUCT *maillon = racine;
    while (maillon != NULL) {
        cout<<"["<<getRatio(maillon)<<"] "<<endl;//<<(int) maillon->coup.x << "," <<(int) maillon->coup.y << "," << maillon->coup.c << ";" << maillon->score << "," << maillon->nbJeux ;
        maillon=maillon->suivant;
        if (maillon != NULL) {
            cout << " | ";
        }
    }
    cout<<endl ;
}


maillonUCT vecteurRave::getMaillon(int num) {
    return tableMaillons[num];
}

int vecteurRave::getNbMaillons() {
    return taille;
}

double vecteurRave::getRatio(int i) {
    return getRatio(&tableMaillons[i]);

}
